package com.ae.content.util;

import com.ae.content.dto.TextstringDTO;
import com.alibaba.fastjson.JSON;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpClientUtil {

    public static String doPost(String pathUrl) {
        try {
            // URL对象创建，指向你想要请求的地址
            URL url = new URL(pathUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为POST
            connection.setRequestMethod("POST");

            // 设置允许输入、输出流
            connection.setDoInput(true);
            connection.setDoOutput(true);

            // 设置连接超时时间
            connection.setConnectTimeout(5000);
            // 设置读取超时时间
            connection.setReadTimeout(5000);

            // 设置请求内容类型，对于没有参数的情况，通常也是设置成application/x-www-form-urlencoded或application/json等
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            // 因为没有请求参数，不需要写入输出流，但需要设置Content-Length为0，表示无内容体
            connection.setRequestProperty("Content-Length", "0");

            // 获取响应码，如果响应码为200表示请求成功
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code : " + responseCode);

            // 读取响应内容
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // 打印响应内容
            System.out.println("Response: " + response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 以post方式调用对方接口方法
     * @param pathUrl
     */
    public static String doPost(String pathUrl, String data){
        OutputStreamWriter out = null;
        BufferedReader br = null;
        String result = "";
        try {
            URL url = new URL(pathUrl);

            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            //设定请求的方法为"POST"，默认是GET
            //post与get的不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setRequestMethod("POST");

            //设置30秒连接超时
            conn.setConnectTimeout(30000);
            //设置30秒读取超时
            conn.setReadTimeout(30000);

            // 设置是否向httpUrlConnection输出，因为这个是post请求，参数要放在http正文内，因此需要设为true, 默认情况下是false;
            conn.setDoOutput(true);
            // 设置是否从httpUrlConnection读入，默认情况下是true;
            conn.setDoInput(true);

            // Post请求不能使用缓存
            conn.setUseCaches(false);

            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");  //维持长链接
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");

            //连接，从上述url.openConnection()至此的配置必须要在connect之前完成，
            conn.connect();

            /**
             * 下面的三句代码，就是调用第三方http接口
             */
            //获取URLConnection对象对应的输出流
            //此处getOutputStream会隐含的进行connect(即：如同调用上面的connect()方法，所以在开发中不调用上述的connect()也可以)。
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            //发送请求参数即数据
            out.write(data);
            //flush输出流的缓冲
            out.flush();

            /**
             * 下面的代码相当于，获取调用第三方http接口后返回的结果
             */
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null){
                result += str;
            }
            System.out.println(result);
            //关闭流
            is.close();
            //断开连接，disconnect是在底层tcp socket链接空闲时才切断，如果正在被其他线程使用就不切断。
            conn.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (out != null){
                    out.close();
                }
                if (br != null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 以get方式调用对方接口方法
     * @param pathUrl
     */
    public static String doGet(String pathUrl){
        BufferedReader br = null;
        String result = "";
        try {
            URL url = new URL(pathUrl);

            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            //设定请求的方法为"GET"，默认是GET
            //post与get的不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setRequestMethod("GET");

            //设置30秒连接超时
            conn.setConnectTimeout(30000);
            //设置30秒读取超时
            conn.setReadTimeout(30000);

            // 设置是否向httpUrlConnection输出，因为这个是post请求，参数要放在http正文内，因此需要设为true, 默认情况下是false;
            conn.setDoOutput(true);
            // 设置是否从httpUrlConnection读入，默认情况下是true;
            conn.setDoInput(true);

            // Post请求不能使用缓存(get可以不使用)
            conn.setUseCaches(false);

            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");  //维持长链接
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

            //连接，从上述url.openConnection()至此的配置必须要在connect之前完成，
            conn.connect();

            /**
             * 下面的代码相当于，获取调用第三方http接口后返回的结果
             */
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String str = "";
            while ((str = br.readLine()) != null){
                result += str;
            }
            System.out.println(result);
            //关闭流
            is.close();
            //断开连接，disconnect是在底层tcp socket链接空闲时才切断，如果正在被其他线程使用就不切断。
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static void main(String[] args) {
        String result = doGet("http://60.204.204.87:80/text2vet?textstring=修改密码");
        double[][] doubles1 = strToDoubleArray(result);

        String result2 = doGet("http://60.204.204.87:80/text2vet?textstring=修改密码");
        double[][] doubles2 = strToDoubleArray(result2);

        double similarity = cosineSimilarity(doubles1, doubles2);
        System.out.println("Cosine Similarity: " + similarity);
    }

    public static double[][] strToDoubleArray(String str) {
        // 去除最外层和最内层数组的括号
        str = str.replace("[", "").replace("]", "").trim();

        // 通过逗号分隔字符串，得到每个数字的字符串表示
        String[] stringNumbers = str.split(",");

        // 初始化double类型的二维数组
        double[][] doubleArray = new double[1][stringNumbers.length];

        // 将每个字符串数字转换为double并放入数组
        for (int i = 0; i < stringNumbers.length; i++) {
            doubleArray[0][i] = Double.parseDouble(stringNumbers[i].trim());
        }
        return doubleArray;
    }

    /**
     * 计算两个double类型二维数组的余弦相似度
     * @param array1 第一个二维数组
     * @param array2 第二个二维数组
     * @return 两个数组的余弦相似度
     */
    public static double cosineSimilarity(double[][] array1, double[][] array2) {
        if (array1 == null || array2 == null || array1.length != array2.length || array1[0].length != array2[0].length) {
            throw new IllegalArgumentException("Arrays must have the same dimensions.");
        }

        double dotProduct = 0.0; // 点积
        double normA = 0.0; // array1的模
        double normB = 0.0; // array2的模

        // 计算点积和各自的模
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array1[0].length; j++) {
                dotProduct += array1[i][j] * array2[i][j];
                normA += Math.pow(array1[i][j], 2);
                normB += Math.pow(array2[i][j], 2);
            }
        }

        // 防止除以0的情况
        if (normA == 0 || normB == 0) {
            return 0;
        }

        // 计算余弦相似度
        return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
    }

}
